package annotation;

import org.junit.Before;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflecTest {
    Class<Dog> clazz = null;

    @Before
    public void before() {
        clazz = Dog.class;
    }

    @Test
    public void createTest() {

    }

    @Test
    public void clazzTest() throws InstantiationException, IllegalAccessException {
        ClassLoader classLoader = clazz.getClassLoader();
        Dog dog = clazz.newInstance();
        dog.setName("tom");
        System.out.println(dog.getName());

    }

    //获取成员变量
    @Test
    public void FieldTest() throws NoSuchFieldException, IllegalAccessException {
        Field[] fields = clazz.getFields();//成员变量的数组
        for (Field field : fields) {
            System.out.println(field.getName());  //这个方法只能拿到public修饰的成员变量
        }
        System.out.println("------------------------");
        Field[] declaredFields = clazz.getDeclaredFields();

        Dog dog = new Dog();
//
//        for (Field declaredField : declaredFields) {
//            System.out.println(declaredField.getName());  //反射可以拿到所有这个class下的成员变量
//        }
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);  //允许访问权限  暴力注入
        name.set(dog, "new"); //直接设置值不能是private
        System.out.println(name.get(dog));

    }

    @Test
    public void methodTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//        Method[] methods = clazz.getMethods();
       Method[] methods = clazz.getDeclaredMethods();
//        for (Method method : methods) {
//            System.out.println(method.getName());
//        }
        Method eat = clazz.getDeclaredMethod("eat");
        Method eat2 = clazz.getDeclaredMethod("eat",String.class);
        Dog dog = new Dog();
        eat.setAccessible(true);
        eat.invoke(dog);
        eat2.invoke(dog,"aaa");
    }
    @Test
    public void constructorTest() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Constructor<Dog> declaredConstructor = clazz.getDeclaredConstructor();
//        System.out.println(declaredConstructor.getName());
//        获取无参构造并且构造对象
        Constructor<Dog> constructor = clazz.getConstructor();
        Dog dog = constructor.newInstance();  //new Dog();

        Constructor<Dog> declaredConstructor1 = clazz.getDeclaredConstructor(String.class);
        Dog dog1 = declaredConstructor1.newInstance("ddd");
        System.out.println(dog1.getName());

    }


    @Test
    public void annotationTest() throws NoSuchFieldException, NoSuchMethodException {
        Annotation[] annotations = clazz.getAnnotations();
        Field name = clazz.getDeclaredField("name");
        Annotation[] annotations1 = name.getAnnotations();
        Method eat = clazz.getDeclaredMethod("eat");
        Annotation[] annotations2 = eat.getAnnotations();
        MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
        String name1 = annotation.name();
        System.out.println(name1);

    }


}